﻿using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Kalman.Extensions;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using System.IO;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Authorization;
using Org.BouncyCastle.Ocsp;
using Kalman.Security;
using Kalman.Enums;
using NLog;
using Microsoft.AspNetCore.Mvc.Controllers;
using Kalman;

namespace QuDao.Api
{
    /// <summary>
    /// 记录API跟踪日志
    /// </summary>
    public class ApiLogAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 是否记录请求日志
        /// </summary>
        public bool IsLogRequest { get; set; } = true;

        /// <summary>
        /// 是否记录响应日志
        /// </summary>
        public bool IsLogResponse { get; set; } = false;

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (!IsLogRequest) return;

            //var actionName = ((ControllerActionDescriptor)context.ActionDescriptor).ActionName;
            //if (actionName == "PayNotify") return;
            var log = LogManager.GetCurrentClassLogger();
            var request = context.HttpContext.Request;
            var body = string.Empty;
            if (request.Method == "POST" && request.ContentLength > 0)
            {
                if (request.HasFormContentType)
                {
                    foreach (var item in request.Form)
                    {
                        body += $"{item.Key}={item.Value}&";
                    }
                    body = body.TrimEnd('&');
                }
                else
                {
                    body = request.GetBodyString();
                }
            }

            var sb = new StringBuilder();
            foreach (var key in request.Headers.Keys)
            {
                switch (key)
                {
                    case "appid":
                        sb.Append($"appid={request.Headers[key]}&");
                        break;
                    case "tid":
                        sb.Append($"tid={request.Headers[key]}&");
                        break;
                    case "accid":
                        sb.Append($"accid={request.Headers[key]}&");
                        break;
                    case "uid":
                        sb.Append($"uid={request.Headers[key]}&");
                        break;
                    //case "Authorization":
                    //    break;
                    default:
                        break;
                }
            }

            var msg = $" => {request.Method} {StringUtil.UrlDecode(request.GetEncodedPathAndQuery())}";

            var header = sb.ToString().TrimEnd('&');
            if (!header.IsNullOrWhiteSpace()) msg = $"{msg} [Header:{header}]";
            if (!body.IsNullOrWhiteSpace()) msg = $"{msg} [{body}]";
            log.Trace(msg);

            //context.HttpContext.Response.Headers["Access-Control-Allow-Origin"] = "*";//解决拦截器添加后跨域不生效的问题，需要在Program里配置IIS webBuilder.UseIIS();
        }

        public override void OnActionExecuted(ActionExecutedContext context)
        {
            if (!IsLogResponse) return;

            var result = context.Result as ObjectResult;
            if (result != null && IsLogResponse)
            {
                var log = LogManager.GetCurrentClassLogger();
                var request = context.HttpContext.Request;
                var msg = $" <= {request.Method} {StringUtil.UrlDecode(request.GetEncodedPathAndQuery())} {result.Value.ToJson()}";
                log.Trace(msg);
            }


        }

    }
}
